/**
 * 20220117:从原SoftLine分离
 */
import {Vector3,Float32BufferAttribute} from "three";
import HardLineGeometry from "./hard-line-geometry";

/**
 * 拐角连续厚度线几何体
 * @param vertices {[Vector3]} 顶点序列
 * @param values {object} 可选参数对象
 *      {
 *           dashSize:0.1,虚线段长（应与材质保持一致）
 *           gapSize:0.1,空白长（应与材质保持一致）
 *      }
 */
export default class SoftLineGeometry extends HardLineGeometry{
    constructor(vertices,values={}){
        super(vertices,values);
    }

    //........................................................public...................................................

    /**
     * 更新数据
     */
    updateGeometry(){
        super.updateGeometry();
        this.geometry.getAttribute('prePosition').copyArray(this._prePositions);
        this.geometry.getAttribute('dirPosition').copyArray(this._dirPositions);
        this.geometry.getAttribute('prePosition').needsUpdate = true;
        this.geometry.getAttribute('dirPosition').needsUpdate = true;
    }

    //.......................................................private...................................................

    _initProps(values) {
        super._initProps(values);
        this._props.remove('arrowMode','arrowLengthRat','arrowWidthRat');
    }
    _initVariable() {
        super._initVariable();
        let s=this._maxSegments;
        let s3=(2*s-3)*6*3;
        this._prePositions=new Float32Array(s3);
        this._dirPositions=new Float32Array(s3);
        this._tV4=new Vector3();
        this._tV5=new Vector3();
        this._tV6=new Vector3();
    }
    _reRangeData(){
        let reRange=super._reRangeData();
        if(reRange){
            let s3=(2*this._maxSegments-3)*6*3;
            this._prePositions=new Float32Array(s3);
            this._dirPositions=new Float32Array(s3);
            this.setAttribute('prePosition', new Float32BufferAttribute(this._prePositions, 3));
            this.setAttribute('dirPosition', new Float32BufferAttribute(this._dirPositions, 3));
        }
        return reRange;
    }
    _rectifyPoints(ps) {
        return ps;
    }
    _getData(){
        this._rectifyVerts=this._rectifyPoints(this._verts);
        if(this._rectifyVerts.length<2){
            console.warn('At least 2 points needed!');
            return;
        }
        this._reRangeData();
        this._pushSolidData(this._rectifyVerts);
    }
    _pushData(i3,i1,c,n,o,dm,pp,dp){
        this._offsets[i1]=o;
        this._dashMarks[i1]=dm;
        this._positions[i3]=c.x;
        this._positions[i3+1]=c.y;
        this._positions[i3+2]=c.z;
        this._nextPositions[i3]=n.x;
        this._nextPositions[i3+1]=n.y;
        this._nextPositions[i3+2]=n.z;

        this._prePositions[i3]=pp.x;
        this._prePositions[i3+1]=pp.y;
        this._prePositions[i3+2]=pp.z;
        this._dirPositions[i3]=dp.x;
        this._dirPositions[i3+1]=dp.y;
        this._dirPositions[i3+2]=dp.z;
    }
    _pushSolidData(vs){
        let n0=this._tV0;
        let n1=this._tV1;
        let pp0=this._tV2;
        let pp1=this._tV3;
        let dp0=this._tV4;
        let dp1=this._tV5;
        let nnp=this._tV6;
        for(let i=0;i<vs.length-1;i++){
            let cp=vs[i];
            let np=vs[i+1];
            if(i===0){
                n0.copy(np);
                n1.subVectors(np,cp).normalize().add(np);

                pp1.copy(cp);
                pp0.subVectors(cp,np).add(cp);
                if(vs[i+2]){
                    nnp.copy(vs[i+2]);
                }else{
                    // nnp.subVectors(np,cp).add(np);
                    nnp.copy(n1);
                }
                dp0.copy(np);
                dp1.copy(nnp);

                this._pushData(0,0,cp,n0,1,1,pp0,dp0);
                this._pushData(3,1,cp,n0,-1,1,pp0,dp0);
                this._pushData(6,2,np,n1,1,1,pp1,dp1);
                this._pushData(9,3,cp,n0,-1,1,pp0,dp0);
                this._pushData(12,4,np,n1,-1,1,pp1,dp1);
                this._pushData(15,5,np,n1,1,1,pp1,dp1);
            }else{
                let i3=18+(i-1)*36;
                let i1=6+(i-1)*12;
                n0.subVectors(cp,vs[i-1]).normalize().add(cp);
                n1.copy(np);

                pp0.copy(vs[i-1]);
                pp1.copy(vs[i-1]);
                dp0.copy(np);
                dp1.copy(np);

                this._pushData(i3,i1,cp,n0,1,1,pp0,dp0);
                this._pushData(i3+3,i1+1,cp,n0,-1,1,pp0,dp0);
                this._pushData(i3+6,i1+2,cp,n1,1,1,pp1,dp1);
                this._pushData(i3+9,i1+3,cp,n0,-1,1,pp0,dp0);
                this._pushData(i3+12,i1+4,cp,n1,-1,1,pp1,dp1);
                this._pushData(i3+15,i1+5,cp,n1,1,1,pp1,dp1);

                n0.copy(np);
                n1.subVectors(np,cp).normalize().add(np);

                if(vs[i+2]){
                    nnp.copy(vs[i+2]);
                }else{
                    // nnp.subVectors(np,cp).add(np);
                    nnp.copy(n1);
                }
                pp0.copy(vs[i-1]);
                pp1.copy(cp);
                dp0.copy(np);
                dp1.copy(nnp);

                this._pushData(i3+18,i1+6,cp,n0,1,1,pp0,dp0);
                this._pushData(i3+21,i1+7,cp,n0,-1,1,pp0,dp0);
                this._pushData(i3+24,i1+8,np,n1,1,1,pp1,dp1);
                this._pushData(i3+27,i1+9,cp,n0,-1,1,pp0,dp0);
                this._pushData(i3+30,i1+10,np,n1,-1,1,pp1,dp1);
                this._pushData(i3+33,i1+11,np,n1,1,1,pp1,dp1);
            }
        }
    }
    _setAttribute() {
        super._setAttribute();
        this.setAttribute('prePosition', new Float32BufferAttribute(this._prePositions, 3));
        this.setAttribute('dirPosition', new Float32BufferAttribute(this._dirPositions, 3));
    }

    get arrowMode(){}
    set arrowMode(n){}
    get arrowLengthRat(){}
    set arrowLengthRat(n){}
    get arrowWidthRat(){}
    set arrowWidthRat(n){}
}